<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // Symbol起源

    // 对象的键名都是字符串类型

    // var zhang = { name: "张三", age: 18, height: "177cm", weight: "70kg" };

    // zhang["name"] = "李四";  //对象属性名 重新赋值 => 后面的就会覆盖前面的

    // console.log(zhang);

    // ES5 的对象属性名都是字符串，这容易造成属性名的冲突。比如，你使用了一个他人提供的对象，但又想为这个对象添加新的方法（mixin 模式），新方法的名字就有可能与现有方法产生冲突

    // console.log(Math); // Math => 官方定义的全局对象

    // 给官方定义一个方法  => 随机指定范围内的整数

    // 你同桌欠你999  -> 你说:今天至少还我100 (100-999)
    // 解析: 100 + 剩余899 (0 - 899)

    // Math.randomInt = function (min, max) {
    //     // 100-999
    //     // 100 + Math.round(Math.random()*(999-100)))
    //     // 100 + Math.floor(Math.random()*(999-100 + 1))
    //     return min + Math.floor(Math.random()*(max - min + 1));
    // }

    // 会覆盖原本的Math.random
    // Math.random = function (min, max) {
    //     return min + Math.floor(Math.random()*(max - min + 1));
    // }

    // (1) 老版本解决方法: 在属性名前加前缀_ => 保证不跟以前的方法重名
    // Math._random = function (min, max) {
    //     return min + Math.floor(Math.random()*(max - min + 1));
    // }

    // (2) 如果有一种机制，保证每个属性的名字都是独一无二的就好了，这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol的原因。


</script>
<script>
    // 2. 消除魔术字符串

    // 魔术字符串指的是，在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。风格良好的代码，应该尽量消除魔术字符串，改由含义清晰的变量代替。

    // 虽然按照值类型比较规则  "+" === "+"  "1" === "1"(数值相等 类型相同)  => true  本质上应该是两个不同的加号

    // 简易计算器封装的方法
    // 魔术字符串版 (两个  "+" === "+")
    // function calc(a, opt, b) {
    //     // a = 10;  opt = "+"  b = 2
    //     var result = null;
    //     switch (opt) {
    //         case "+": result = a * 1 + b * 1; break
    //         case "-": result = a - b; break
    //         case "*": result = a * b; break
    //         case "/": result = a / b; break
    //         case "%": result = a % b; break
    //     }
    //     return result;
    // }

    // var res = calc(10, "+", 2);
    // console.log(res);


    // 消除魔术字符串
    // 优化  自己和自己比
    // var options = {
    //     add: "+",
    //     reduce: "-",
    //     multip: "*",
    //     divide: "/",
    //     mod: "%",
    // }
    // options.add => "+"

    var options = {
        add: Symbol("+"),
        reduce: Symbol("-"),
        multip: Symbol("*"),
        divide: Symbol("/"),
        mod: Symbol("%"),
    }

    function calc(a, opt, b) {
        // a = 10;  opt = options.add  b = 2
        var result = null;
        switch (opt) {
            case options.add: result = a * 1 + b * 1; break
            case options.reduce: result = a - b; break
            case options.multip: result = a * b; break
            case options.divide: result = a / b; break
            case options.mod: result = a % b; break
        }
        return result;
    }

    var res = calc(10, options.add, 2);
    console.log(res);















</script>

</html>